package prv.pursuivant.core;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.google.inject.Inject;
import com.google.inject.internal.MapMaker;

public class AchievTypesTreeImpl implements AchievTypesTree {

	private final AchievType root;
	private final List<AchievType> allTheAchievements;
	private Map<String, AchievType> cacheMap;

	@Inject
	public AchievTypesTreeImpl(List<AchievType> allTheAchievements,
			AchievType root) {
		this.root = root;
		this.allTheAchievements = allTheAchievements;
	}

	/**
	 * 
	 * @see prv.pursuivant.core.AchievTypesTree#findAchievTypeById(java.lang
	 *      .String)
	 */
	@Override
	public AchievType findAchievTypeById(String id) {
		// TODO: this crap is because of XStream - consider wrapping/adapt
		// classes for serializaption
		if (null == cacheMap)
			cacheMap = new MapMaker().softKeys().softValues().expiration(10,
					TimeUnit.MINUTES).makeMap();

		// this is ok:
		if (root.getId().equals(id))
			return root;
		else if (cacheMap.containsKey(id))
			return cacheMap.get(id);
		else
			for (AchievType achiev : allTheAchievements) {
				if (achiev.getId().equals(id)) {
					cacheMap.put(id, achiev);
					return achiev;
				}
			}
		throw new IllegalArgumentException("No achievement with id = '" + id
				+ "'");
	}

	@Override
	public AchievType getRoot() {
		return root;
	}

	@Override
	public String getRootId() {
		return root.getId();
	}

}
